from django.shortcuts import render, redirect, HttpResponse
import re   # re(regular expression)正则表达式模块:主要功能是从字符串(string)中通过特定的模式(pattern)，搜索想要找到的内容。
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django import forms
from Rufe import models
from django.http import JsonResponse, HttpResponseRedirect
from django.urls import reverse
from django.contrib import auth
# from captcha.fields import CaptchaField


def name_valid(value):
    name_re = re.compile(r'^[\d]+')
    ret = name_re.match(value)
    if ret:
        raise ValidationError('用户名不能以数字开头！')


class LoginForm(forms.Form):
    username = forms.CharField(label="账号", required=True, min_length=1)
    password = forms.CharField(label="密码", required=True, min_length=1,
                               widget=forms.PasswordInput)


class ResetForm(forms.Form):
    old_password = forms.CharField(
        required=True,
        label='密码：',
        min_length=1,
        max_length=10,
        help_text='长度6到10位！',
        initial='',
        error_messages={
            'required': '旧密码不能为空！'
        },
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
    )
    new_password = forms.CharField(
        required=True,
        label='密码：',
        min_length=1,
        max_length=10,
        help_text='长度6到10位！',
        initial='',
        error_messages={
            'required': '新密码不能为空！',
            'min_length': '长度不能少于6位！',
            'max_length': '长度不能超过10位！',
        },
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
    )
    r_new_password = forms.CharField(
        required=True,
        label='确认新密码：',
        min_length=1,
        max_length=10,
        help_text='长度6到10位！',
        initial='',
        error_messages={
            'required': '确认新密码不能为空！',
            'min_length': '长度不能少于6位！',
            'max_length': '长度不能超过10位！',
        },
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
    )


class RegisterForm(forms.Form):
    username = forms.CharField(
        required=True,
        label='账号：',
        min_length=1,
        max_length=30,
        help_text='只能有字母数字下划线组成，且不能以数字开头，长度6到30位！',
        error_messages={
            'required': '账号不能为空！',
            'min_length': '长度不能少于3位！',
            'max_length': '长度不能超过30位！',
        },
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        validators=[RegexValidator(r'^[a-zA-Z0-9_]+$', '用户名只能包含字母数字下划线！'), name_valid],
        )
    password = forms.CharField(
        required=True,
        label='密码：',
        min_length=1,
        max_length=10,
        help_text='长度6到10位！',
        initial='',
        error_messages={
            'required': '密码不能为空！',
            'min_length': '长度不能少于6位！',
            'max_length': '长度不能超过10位！',
        },
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
    )
    r_password = forms.CharField(
        required=True,
        label='确认密码：',
        min_length=1,
        max_length=10,
        help_text='长度6到10位！',
        initial='',
        error_messages={
            'required': '确认密码不能为空！',
            'min_length': '长度不能少于6位！',
            'max_length': '长度不能超过10位！',
        },
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
    )
    phone = forms.CharField(
        max_length=11,
        required=True,
        label='phone',
        error_messages={
            'required': 'phone不能为空！',
        },
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        # validators=[RegexValidator(r'^1[345678]\d{9}', message='输入手机格式不正确!')]
    )
    # captcha = CaptchaField(label='验证码')


# 批量给form表单里的字段加样式
def __init__(self, *args, **kwargs):
    super(RegisterForm, self).__init__(*args, **kwargs)
    for field in self.fields:
        self.fields[field].widget.attrs.update({'class': 'form-control'})


# 全局钩子，此处用来判断两次输入的密码
# 在Fom类中定义 clean() 方法，就能够实现对字段进行全局校验。
def clean(self):
    password = self.cleaned_data.get('password')
    r_password = self.cleaned_data.get('r_password')
    if password != r_password:
        self.add_error('r_password', '两次密码不一致！')
        raise ValidationError('两次密码不一致！')
    else:
        return self.cleaned_data


# 局部钩子函数
# 在Fom类中定义 clean_字段名() 方法，就能够实现对特定字段进行校验。如果通过,将该字段返回，如果失败，抛异常(ValidationError)
def clean_username(self):
    # 目的：如果用户名已经注册，则报异常
    username = self.cleaned_data.get('username')
    ret = models.UserProfile.objects.filter(username=username)
    if not ret:
        return username
    else:
        raise ValidationError('用户名已经被注册')


def clean_password(self):
    pass
    return self.cleaned_data.get('password')


def clean_r_password(self):
    pass
    return self.cleaned_data.get('r_password')


def clean_phone(self):
    phone = self.cleaned_data.get('phone')
    phone_obj = models.UserProfile.objects.filter(phone=phone).first().exists()
    if not phone_obj:
        return phone
    else:
        raise ValidationError('该电话已经被注册！')


# 注册
def register(request):
    if request.method == 'GET':
        form = RegisterForm()
        return render(request, 'account/register.html', {'form': form})
    elif request.method == 'POST':
        # request.POST拿到前端传的数据
        form = RegisterForm(request.POST)
        # 是否验证
        if form.is_valid():
            # form.cleaned_data,获取校验通过的数据，字典类型
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            phone = form.cleaned_data['phone']
            # 插入已经校验通过的数据，通过解包字典转换成key=value的方式
            models.UserProfile.objects.create_user(username=username, password=password, phone=phone)
            return render(request, 'account/success.html', {'username': username})
        else:
            all_error = form.errors.get('__all__')
            if all_error:
                all_error = all_error[0]
            print(form.errors)
            print(form.errors.get('__all__'))
        return render(request, 'account/register.html', {'form': form})


# 登录
def login(request):
    if request.method == 'GET':
        login_form = LoginForm()
        return render(request, 'account/login.html', locals())

    elif request.method == 'POST':
        login_form = LoginForm(request.POST)
        if login_form.is_valid():
            username = login_form.cleaned_data['username']
            password = login_form.cleaned_data['password']
            user = auth.authenticate(username=username, password=password)

            if user:
                auth.login(request, user)
                response = HttpResponse('登录成功')

                import datetime
                # 设置Cookie
                current_date = datetime.datetime.utcnow()
                current_date = current_date + datetime.timedelta(seconds=10)
                response.set_cookie('username', username, expires=current_date, httponly=True)
                # 设置Session
                now = datetime.datetime.now().strftime('%Y-%m-%d %X')
                request.session['now'] = now
                request.session['is_login'] = True
                request.session['username'] = username
                # 浏览器关闭时，session失效
                request.session.set_expiry(0)
                return HttpResponseRedirect(reverse('index'))
            else:
                return render(request, "account/login.html", {"msg": u"用户名或者密码错误!"})
        else:
            return render(request, "account/login.html", {"login_form": login_form})


# 访问认证
def index(request):
    is_login = request.session.get('is_login')
    # if request.user.is_authenticated:
    if is_login:
        if request.method == 'GET':
            username = request.COOKIES.get('username')

            name = request.session.get('username')
            now = request.session.get('now')
            return render(request, 'account/index.html', locals())
    else:
        return HttpResponseRedirect(reverse('login'))


# 注销
def logout(request):
    auth.logout(request)
    request.session.flush()
    return HttpResponseRedirect(reverse('index'))


# 修改密码
def reset_pwd(request):
    if request.user.is_authenticated:
        if request.method == 'GET':
            reset_form = ResetForm()
            return render(request, 'account/reset_pwd.html', {'reset_form': reset_form})
        elif request.method == 'POST':
            reset_form = ResetForm(request.POST)
            old_password = reset_form('old_password')
            new_password = reset_form('new_password')
            r_new_password = reset_form('r_new_password')
            # ret=request.user.check_password(old_password)
            # print(ret)
            if request.user.check_password(old_password):
                if new_password == r_new_password:
                    request.user.set_password(new_password)
                    request.user.save()
                    return JsonResponse({'status': True, 'info': '操作成功！', 'url': reverse('index')})
                else:
                    return JsonResponse({'status': False, 'info': '两次新密码不一致！', 'url': ''})
            else:
                return JsonResponse({'status': False, 'info': '操作失败：原密码输入有误！', 'url': ''})
        return JsonResponse({'status': False, 'info': '操作失败！', 'url': ''})

    else:
        return redirect('login')
